/*
 static void avStreamFPSTimeBase(AVStream *st, CGFloat defaultTimeBase, CGFloat *pFPS, CGFloat *pTimeBase)
 {
 CGFloat fps, timebase;
 
 if (st->time_base.den && st->time_base.num)
 timebase = av_q2d(st->time_base);
 else if(st->codec->time_base.den && st->codec->time_base.num)
 timebase = av_q2d(st->codec->time_base);
 else
 timebase = defaultTimeBase;
 
 if (st->codec->ticks_per_frame != 1) {
 printf("WARNING: st.codec.ticks_per_frame=%d", st->codec->ticks_per_frame);
 //timebase *= st->codec->ticks_per_frame;
 }
 
 if (st->avg_frame_rate.den && st->avg_frame_rate.num)
 fps = av_q2d(st->avg_frame_rate);
 else if (st->r_frame_rate.den && st->r_frame_rate.num)
 fps = av_q2d(st->r_frame_rate);
 else
 fps = 1.0 / timebase;
 
 if (pFPS)
 *pFPS = fps;
 if (pTimeBase)
 *pTimeBase = timebase;
 }
 int mainx()
 {
 AVFormatContext *pFormatCtx;
 int             i, videoStream;
 AVCodecContext  *pCodecCtx;
 AVCodec         *pCodec;
 AVFrame         *pFrame;
 AVFrame         *pFrameRGB;
 AVPacket        packet;
 int             frameFinished;
 int             numBytes;
 uint8_t         *buffer;
 struct SwsContext *img_convert_ctx;
 
 const char* filename = "/Users/wangjiangang/DCT/360.mp4";
 //    if(argc < 2)
 //    {
 //        printf("Please provide a movie file\n");
 //        return -1;
 //    }
 // Register all formats and codecs
 // 初始化ffmpeg库
 av_register_all();
 pFormatCtx = avformat_alloc_context();
 if (!pFormatCtx)
 return -1;
 // Open video file
 if (avformat_open_input(&pFormatCtx, filename, NULL, NULL) < 0) {
 return -1;
 }
 //    av_seek_frame(<#AVFormatContext *s#>, <#int stream_index#>, <#int64_t timestamp#>, <#int flags#>)
 // Retrieve stream information
 // 查找文件的流信息
 if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
 return -1;
 }
 
 // Dump information about file onto standard error
 // dump只是一个调试函数，输出文件的音、视频流的基本信息：帧率、分辨率、音频采样等等
 av_dump_format(pFormatCtx, 0, filename, 0);
 
 // Find the first video stream
 // 遍历文件的流，找到第一个视频流，并记录流的编码信息
 videoStream=-1;
 for(i=0; i<pFormatCtx->nb_streams; i++)
 {
 if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)
 {
 videoStream=i;
 break;
 }
 }
 if(videoStream==-1)
 return -1; // Didn't find a video stream
 
 // Get a pointer to the codec context for the video stream
 // 得到视频流编码的上下文指针
 pCodecCtx=pFormatCtx->streams[videoStream]->codec;
 
 // construct the scale context, conversing to PIX_FMT_RGB24
 // 根据编码信息设置渲染格式
 img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt,
 pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);
 if(img_convert_ctx == NULL)
 {
 fprintf(stderr, "Cannot initialize the conversion context!\n");
 //      exit(1);
 return -1;
 }
 
 // Find the decoder for the video stream
 // 在库里面查找支持该格式的解码器
 pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
 if(pCodec==NULL)
 {
 fprintf(stderr, "Unsupported codec!\n");
 return -1; // Codec not found
 }
 // Open codec
 // 打开解码器
 //    if(avcodec_open(pCodecCtx, pCodec)<0)
 //        return -1; // Could not open codec
 if ( avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {
 av_log(NULL, AV_LOG_ERROR, "Cannot open video decoder\n");
 return -1;
 }
 // Allocate video frame
 // 分配一个帧指针，指向解码后的原始帧
 pFrame=av_frame_alloc();
 if (!pFrame) {
 avcodec_close(pCodecCtx);
 return -1;
 }
 float _fps=0;
 float _videoTimeBase=0;
 AVStream *st = pFormatCtx->streams[videoStream];
 avStreamFPSTimeBase(st, 0.04, &_fps, &_videoTimeBase);
 
 // Read frames and save first five frames to disk
 i=0;
 while(av_read_frame(pFormatCtx, &packet)>=0) // 读取一个帧
 {
 // Is this a packet from the video stream?
 float minDuration=0.1;
 float decodedDuration=0;
 if(packet.stream_index==videoStream)
 {
 int pktSize = packet.size;
 while (pktSize > 0) {
 
 int len = avcodec_decode_video2(pCodecCtx,
 pFrame,
 &frameFinished,
 &packet);
 
 if (len < 0) {
 printf("decode video error, skip packet\n");
 break;
 }
 
 if (frameFinished) {
 printf("frameFinished:%d\n",len);
 
 const int64_t frameDuration = av_frame_get_pkt_duration(pFrame);
 int64_t duration=0;
 if (frameDuration) {
 
 duration = frameDuration * _videoTimeBase;
 duration += pFrame->repeat_pict * _videoTimeBase * 0.5;
 
 } else {
 duration = 1.0 / _fps;
 }
 
 if (duration) {
 decodedDuration += duration;
 //                        if (decodedDuration > minDuration)
 //                            finished = YES;
 }
 }
 
 if (0 == len)
 break;
 
 pktSize -= len;
 }
 }
 
 // Free the packet that was allocated by av_read_frame
 // 释放读取的帧内存
 av_free_packet(&packet);
 }
 
 // Free the RGB image
 av_free(buffer);
 av_free(pFrameRGB);
 
 // Free the YUV frame
 av_free(pFrame);
 
 // Close the codec
 avcodec_close(pCodecCtx);
 
 // Close the video file
 avformat_free_context(pFormatCtx);
 
 return 0;
 }
 */
#include "watermark.h"
#include "data.h"
#include "function.h"

#include <fcntl.h>
#include <sys/stat.h>
//#include <io.h>
//#include "process.h"
#include "math.h"
#include <string>
#include <stdlib.h>

using namespace std;

int nGold = 16;
int nGoldLen = 127;
short gold[][127] =
{
    {1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1
        , 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1
        , 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1
        , 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1
        , 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1
        , -1, -1, -1, -1, -1, 1, -1},
    {-1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1
        , 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1
        , -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1
        , 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1
        , -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1
        , 1, -1, -1, -1, 1, -1, -1},
    {-1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1
        , 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1
        , -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1
        , -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1
        , -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1
        , 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1},
    {-1, 1, -1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1
        , -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1
        , 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1
        , 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1
        , -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1
        , 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1},
    {-1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1
        , -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1
        , 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1
        , 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1
        , 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1
        , -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1},
    {-1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1
        , -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1
        , 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1
        , -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1
        , -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1
        , -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1},
    {-1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1
        , -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1
        , -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1
        , 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1
        , 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1
        , -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1},
    {1, 1,  1,  1, -1,  1, -1, -1,  1,  1,  1,  1, -1, -1,  1,  1, -1,  1, -1, -1, -1, -1, -1
        , -1, -1,  1, -1,  1, -1, -1,  1, -1, -1, -1,  1, -1, -1, -1, -1,  1,  1,  1, -1, -1, -1,  1
        , -1,  1,  1,  1, -1,  1, -1,  1, -1, -1, -1,  1,  1,  1,  1,  1,  1, -1, -1, -1, -1,  1, -1
        , -1,  1,  1, -1, -1,  1,  1,  1, -1,  1,  1, -1,  1,  1, -1, -1, -1,  1,  1, -1, -1, -1, -1
        , -1,  1,  1, -1,  1,  1,  1,  1,  1, -1,  1,  1,  1, -1, -1,  1, -1,  1, -1,  1, -1,  1,  1
        , -1, -1,  1, -1, -1,  1, -1,  1,  1, -1,  1, -1},
    {1, -1,  1, -1, -1,  1, -1, -1, -1,  1, -1, -1, -1, -1,  1,  1,  1, -1, -1, -1,  1, -1,  1
        ,  1,  1, -1,  1, -1,  1, -1, -1, -1,  1,  1,  1,  1,  1,  1, -1, -1, -1, -1,  1, -1, -1,  1
        ,  1, -1, -1,  1,  1,  1, -1,  1,  1, -1,  1,  1, -1, -1, -1,  1,  1, -1, -1, -1, -1, -1,  1
        ,  1, -1,  1,  1,  1,  1,  1, -1,  1,  1,  1, -1, -1,  1, -1,  1, -1,  1, -1,  1,  1, -1, -1
        ,  1, -1, -1,  1, -1,  1,  1, -1,  1, -1,  1,  1,  1,  1, -1,  1, -1, -1,  1,  1,  1,  1, -1
        , -1,  1,  1, -1,  1, -1, -1, -1, -1, -1, -1, -1},
    {-1,  1, -1,  1, -1, -1,  1, -1, -1, -1,  1, -1, -1, -1, -1,  1,  1,  1, -1, -1, -1,  1, -1
        ,  1,  1,  1, -1,  1, -1,  1, -1, -1, -1,  1,  1,  1,  1,  1,  1, -1, -1, -1, -1,  1, -1, -1
        ,  1,  1, -1, -1,  1,  1,  1, -1,  1,  1, -1,  1,  1, -1, -1, -1,  1,  1, -1, -1, -1, -1, -1
        ,  1,  1, -1,  1,  1,  1,  1,  1, -1,  1,  1,  1, -1, -1,  1, -1,  1, -1,  1, -1,  1,  1, -1
        , -1,  1, -1, -1,  1, -1,  1,  1, -1,  1, -1,  1,  1,  1,  1, -1,  1, -1, -1,  1,  1,  1,  1
        , -1, -1,  1,  1, -1,  1, -1, -1, -1, -1, -1, -1},
    {1, -1, -1, -1, -1,  1,  1,  1, -1, -1, -1,  1, -1,  1,  1,  1, -1,  1, -1,  1, -1, -1, -1
        ,  1,  1,  1,  1,  1,  1, -1, -1, -1, -1,  1, -1, -1,  1,  1, -1, -1,  1,  1,  1, -1,  1,  1
        , -1,  1,  1, -1, -1, -1,  1,  1, -1, -1, -1, -1, -1,  1,  1, -1,  1,  1,  1,  1,  1, -1,  1
        ,  1,  1, -1, -1,  1, -1,  1, -1,  1, -1,  1,  1, -1, -1,  1, -1, -1,  1, -1,  1,  1, -1,  1
        , -1,  1,  1,  1,  1, -1,  1, -1, -1,  1,  1,  1,  1, -1, -1,  1,  1, -1,  1, -1, -1, -1, -1
        , -1, -1, -1,  1, -1,  1, -1, -1,  1, -1, -1, -1},
    {-1, -1, -1,  1,  1,  1, -1, -1, -1,  1, -1,  1,  1,  1, -1,  1, -1,  1, -1, -1, -1,  1,  1
        ,  1,  1,  1,  1, -1, -1, -1, -1,  1, -1, -1,  1,  1, -1, -1,  1,  1,  1, -1,  1,  1, -1,  1
        ,  1, -1, -1, -1,  1,  1, -1, -1, -1, -1, -1,  1,  1, -1,  1,  1,  1,  1,  1, -1,  1,  1,  1
        , -1, -1,  1, -1,  1, -1,  1, -1,  1,  1, -1, -1,  1, -1, -1,  1, -1,  1,  1, -1,  1, -1,  1
        ,  1,  1,  1, -1,  1, -1, -1,  1,  1,  1,  1, -1, -1,  1,  1, -1,  1, -1, -1, -1, -1, -1, -1
        , -1,  1, -1,  1, -1, -1,  1, -1, -1, -1,  1, -1},
    {-1, -1,  1, -1, -1, -1,  1, -1, -1, -1, -1,  1,  1,  1, -1, -1, -1,  1, -1,  1,  1,  1, -1
        ,  1, -1,  1, -1, -1, -1,  1,  1,  1,  1,  1,  1, -1, -1, -1, -1,  1, -1, -1,  1,  1, -1, -1
        ,  1,  1,  1, -1,  1,  1, -1,  1,  1, -1, -1, -1,  1,  1, -1, -1, -1, -1, -1,  1,  1, -1,  1
        ,  1,  1,  1,  1, -1,  1,  1,  1, -1, -1,  1, -1,  1, -1,  1, -1,  1,  1, -1, -1,  1, -1, -1
        ,  1, -1,  1,  1, -1,  1, -1,  1,  1,  1,  1, -1,  1, -1, -1,  1,  1,  1,  1, -1, -1,  1,  1
        , -1,  1, -1, -1, -1, -1, -1, -1, -1,  1, -1,  1},
    {1,  1,  1, -1,  1, -1, -1,  1,  1,  1,  1, -1, -1,  1,  1, -1,  1, -1, -1, -1, -1, -1, -1
        , -1,  1, -1,  1, -1, -1,  1, -1, -1, -1,  1, -1, -1, -1, -1,  1,  1,  1, -1, -1, -1,  1, -1
        ,  1,  1,  1, -1,  1, -1,  1, -1, -1, -1,  1,  1,  1,  1,  1,  1, -1, -1, -1, -1,  1, -1, -1
        ,  1,  1, -1, -1,  1,  1,  1, -1,  1,  1, -1,  1,  1, -1, -1, -1,  1,  1, -1, -1, -1, -1, -1
        ,  1,  1, -1,  1,  1,  1,  1,  1, -1,  1,  1,  1, -1, -1,  1, -1,  1, -1,  1, -1,  1,  1, -1
        , -1,  1, -1, -1,  1, -1,  1,  1, -1,  1, -1,  1},
    {1, -1, -1, -1,  1, -1, -1, -1, -1,  1,  1,  1, -1, -1, -1,  1, -1,  1,  1,  1, -1,  1, -1
        ,  1, -1, -1, -1,  1,  1,  1,  1,  1,  1, -1, -1, -1, -1,  1, -1, -1,  1,  1, -1, -1,  1,  1
        ,  1, -1,  1,  1, -1,  1,  1, -1, -1, -1,  1,  1, -1, -1, -1, -1, -1,  1,  1, -1,  1,  1,  1
        ,  1,  1, -1,  1,  1,  1, -1, -1,  1, -1,  1, -1,  1, -1,  1,  1, -1, -1,  1, -1, -1,  1, -1
        ,  1,  1, -1,  1, -1,  1,  1,  1,  1, -1,  1, -1, -1,  1,  1,  1,  1, -1, -1,  1,  1, -1,  1
        , -1, -1, -1, -1, -1, -1, -1,  1, -1,  1, -1, -1},
    {-1, -1, -1, -1,  1,  1,  1, -1, -1, -1,  1, -1,  1,  1,  1, -1,  1, -1,  1, -1, -1, -1,  1
        ,  1,  1,  1,  1,  1, -1, -1, -1, -1,  1, -1, -1,  1,  1, -1, -1,  1,  1,  1, -1,  1,  1, -1
        ,  1,  1, -1, -1, -1,  1,  1, -1, -1, -1, -1, -1,  1,  1, -1,  1,  1,  1,  1,  1, -1,  1,  1
        ,  1, -1, -1,  1, -1,  1, -1,  1, -1,  1,  1, -1, -1,  1, -1, -1,  1, -1,  1,  1, -1,  1, -1
        ,  1,  1,  1,  1, -1,  1, -1, -1,  1,  1,  1,  1, -1, -1,  1,  1, -1,  1, -1, -1, -1, -1, -1
        , -1, -1,  1, -1,  1, -1, -1,  1, -1, -1, -1,  1}
};

/*
 short wcode16[]=
 {
	1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1
 };
 */
short wcode16[]=
{
    1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1
};

short wcode32[]=
{
    1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1,
    -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1
};
/*
 short wcode32[]=
 {
	1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1,  1, -1,  1,  1, -1, -1,  1,  1,  1, -1,  1, -1,
	1, 1,  1, -1,  1, -1,  1, -1, -1
 };
 */

short wcode48[]=
{
    1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1,
    -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1,
    -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1
};

short wcode64[]=
{
    1, -1, -1,  1, -1, -1,  1, -1, -1, -1,  1, -1,  1,  1,  1,  1, -1, -1,  1,  1,  1,  1,  1,
    1, -1,  1, -1,  1,  1, -1, -1, -1, -1,  1, -1,  1,  1,  1, -1,  1,  1, -1, -1, -1,  1, -1,
    1, -1, -1,  1, -1,  1, -1,  1,  1, -1,  1,  1, -1,  1, -1, -1,  1,  1
};


int zigzag[64] = {
    0, 1, 5, 6,14,15,27,28,
    2, 4, 7,13,16,26,29,42,
    3, 8,12,17,25,30,41,43,
    9,11,18,24,31,40,44,53,
    10,19,23,32,39,45,52,54,
    20,22,33,38,46,51,55,60,
    21,34,37,47,50,56,59,61,
    35,36,48,49,57,58,62,63
};

int lmdctac[] =
{
    2,3,4,5,9,10,11,12,16,17,18,19,24,25,26,32,33,40
};

//CString m_strShowText;

//DWORD WINAPI WatermarkThreadProc(LPVOID)
//{
//    if(YUVWatermark(m_strFileName))
//        m_strShowText = _T("水印成功嵌入文件!\r\n");
//    else
//        m_strShowText = _T("水印嵌入失败!\r\n");
//    
//    if(m_bStop) m_strShowText = _T("水印嵌入停止!\r\n");
//    
//    ShowText(m_strShowText);
//    m_bBusy = FALSE;
//    m_bStop = FALSE;
//    
//    _endthread();
//    return 0;
//}
//
//DWORD WINAPI DetectThreadProc(LPVOID)
//{
//    if(YUVWMDetect(m_strFileName))
//        m_strShowText = _T("水印检测完成!\r\n");
//    else
//        m_strShowText = _T("水印检测失败!\r\n");
//    
//    if(m_bStop) m_strShowText = _T("水印检测停止!\r\n");
//    
//    ShowText(m_strShowText);
//    m_bBusy = FALSE;
//    m_bStop = FALSE;
//    
//    _endthread();
//    return 0;
//}

bool YUVWatermark(std::string strFileName)
{
    short w1;
    w1 = (short)(m_dvwmSysParam.nWmInfo);
    
//    string strFileName1 = strFileName;
//    int index  = strFileName1.ReverseFind('\\');
//    string strPath = strFileName1.Left(index);
//    strFileName1 = strFileName1.Right(strFileName1.GetLength() - index);
//    index  = strFileName1.ReverseFind('.');
//    if(index <= 0)
//    {
//        strFileName1 = strFileName + _T("_w");
//    }
//    else
//    {
//        CString strExt = strFileName1.Right(strFileName1.GetLength() - index);
//        strFileName1 = strFileName1.Left(index);
//        strFileName1 = strFileName1 + _T("_w");
//        strFileName1 = strFileName1 + strExt;
//        strFileName1 = strPath + strFileName1;
//    }
    
//    CFile file;
//    if(!file.Open(strFileName, CFile::modeRead | CFile::typeBinary))
//        return FALSE;
//    
//    CFile file1;
//    if(!file1.Open(strFileName1, CFile::modeCreate | CFile::modeReadWrite | CFile::typeBinary))
//    {
//        file.Close();
//        return FALSE;
//    }
    
    int nWidth = m_dvwmVideoFrame.nWidth;
    int nHeight = m_dvwmVideoFrame.nHeight;
    
    unsigned char *y = NULL;
    unsigned char *u = NULL;
    unsigned char *v = NULL;
    
    string strText;
    
    y = (unsigned char*)malloc(nHeight*nWidth);
    u = (unsigned char*)malloc(nHeight*nWidth/2/2);
    v = (unsigned char*)malloc(nHeight*nWidth/2/2);
    
    unsigned int nKey;
    short goldc[64][63];
    unsigned char istatus[8][20];
    unsigned char cstatus[20];
    unsigned char cstatus1[20];
    unsigned char rn;
    int n_a, n_b, n_a_c, n_b_c;
    
    if(m_dvwmSysParam.nFrameSync)
    {
        initstatus(istatus, 8, m_dvwmSysParam.nWmKey);
        gold6(goldc);
        n_a_c = 32;
        n_b_c = 4;
        n_a = n_a_c;
        n_b = 0;
    }
    
    int n = 0;
    while(1)
    {
        if(m_bStop) break;
        int len=0;
//        int len = file.Read(y, nHeight*nWidth);
//        if(len != nHeight*nWidth) break;
//        len = file.Read(u, nHeight*nWidth/2/2);
//        if(len != nHeight*nWidth/2/2) break;
//        len = file.Read(v, nHeight*nWidth/2/2);
        if(len != nHeight*nWidth/2/2) break;
        
        if(m_dvwmSysParam.nGeometric) UMeanWatermark(u, nWidth/2, nHeight/2, w1, n%127);
        if(m_dvwmSysParam.nFrameSync)
        {
            if(n_a >= n_a_c)
            {
                srand((unsigned)time(NULL));
                int m = rand()*8/(RAND_MAX+1);
                memcpy(cstatus, istatus[m], 20);
                kt(cstatus, 0, nKey);
                n_a = 0;
                n_b = 0;
            }
            
            YSyncWatermark(y, nWidth, nHeight, goldc, nKey);
            
            n_a ++;
            n_b ++;
            if(n_b >= n_b_c)
            {
                n_b = 0;
                srand((unsigned)time(NULL));
                rn = (unsigned char)(rand()*4/(RAND_MAX+1));
                nextstatus(cstatus, cstatus1, nKey, rn);
                memcpy(cstatus, cstatus1, 20);
                kt(cstatus, nKey, nKey);
            }
        }
        
//        file1.Write(y, nHeight*nWidth);
//        file1.Write(u, nHeight*nWidth/2/2);
//        file1.Write(v, nHeight*nWidth/2/2);
        
        n++;
        if(n % 256 == 0)
        {
//            strText.Format(_T("%d帧已嵌入水印...\r\n"), n);
//            ShowText(strText);
        }
    };
    
//    strText.Format(_T("共在%d帧中嵌入水印.\r\n"), n);
//    ShowText(strText);
    
    if(y) free(y);
    if(u) free(u);
    if(v) free(v);
    
//    file.Close();
//    file1.Close();
    
    if(n == 0) return false;
    return true;
}

//bool YUVWMDetect(string strFileName)
//{
//    CFile file;
//    if(!file.Open(strFileName, CFile::modeRead | CFile::typeBinary))
//        return FALSE;
//    
//    int nWidth = m_dvwmVideoFrame.nWidth;
//    int nHeight = m_dvwmVideoFrame.nHeight;
//    
//    unsigned char *y = NULL;
//    unsigned char *u = NULL;
//    y = (unsigned char*)malloc(nHeight*nWidth);
//    u = (unsigned char*)malloc(nHeight*nWidth/2/2);
//    
//    double dbVal[16];
//    double dbSum[16];
//    double dbSum1[16];
//    memset(dbVal, 0, sizeof(double)*16);
//    memset(dbSum, 0, sizeof(double)*16);
//    memset(dbSum1, 0, sizeof(double)*16);
//    for(int i=0; i<16; i++)
//    {
//        for(int j=0; j<127; j++)
//            dbSum1[i] += (double)gold[i][j];
//    }
//
//    unsigned int nKey;
//    short goldc[64][63];
//    unsigned char istatus[8][20];
//    unsigned char cstatus[20];
//    unsigned char cstatus1[20];
//    double dbSyncVal = 0.F;
//    unsigned char squeue[16][20];
//    unsigned int kqueue[16];
//    int n_k = 0;
//    initstatus(istatus, 8, m_dvwmSysParam.nWmKey);
//    gold6(goldc);
//    
//    BOOL bSync[64];
//    int n = 0;
//    while(1)
//    {
//        if(m_bStop) break;
//        
//        int len = file.Read(y, nHeight*nWidth);
//        if(len != nHeight*nWidth) break;
//        len = file.Read(u, nHeight*nWidth/2/2);
//        if(len != nHeight*nWidth/2/2) break;
//        
//        //detect u mean watermark
//        UMeanWMDetect(u, nWidth/2, nHeight/2, n%127, dbVal, dbSum);
//        
//        n++;
//        
//        if((n % 127) == 0)
//        {
//            CString strDetect;
//            
//            int nVal = 0;
//            int nDetect = 0;
//            for(int i=15; i>=0; i--)
//            {
//                dbSum[i] /= 127.0;
//                dbVal[i] -= dbSum[i]*dbSum1[i];
//                dbVal[i] /= (double)(nWidth/16)*(double)(nHeight/16)*127.0;
//                
//                if(dbVal[i] >= 2.5)
//                {
//                    strDetect += _T("1");
//                    nVal |= 0x0001 << i;
//                    nDetect ++;
//                }
//                else if(dbVal[i] <= -2.5)
//                {
//                    strDetect += _T("0");
//                    nDetect ++;
//                }
//                else
//                    strDetect += _T("?");
//            }
//            
//            CString strText;
//            strText.Format(_T("%d~%d帧"), n-127, n-1);
//            if(nDetect == 16)
//            {
//                strText += _T("检测到完整抗几何变换水印信息:");
//                strText += strDetect;
//                strDetect.Format(_T("(%d)"), nVal);
//                strText += strDetect;
//                strText += _T(".\r\n");
//            }
//            else if(nDetect <= 2)
//            {
//                strText += _T("没有检测到抗几何变换水印信息.\r\n");
//            }
//            else if(nDetect < 8)
//            {
//                strText += _T("检测到小部分抗几何变换水印信息:");
//                strText += strDetect;
//                strText += _T(".\r\n");
//            }
//            else
//            {
//                strText += _T("检测到大部分抗几何变换水印信息:");
//                strText += strDetect;
//                strText += _T(".\r\n");
//            }
//            
//            ShowText(strText);
//            
//            memset(dbVal, 0, sizeof(double)*16);
//            memset(dbSum, 0, sizeof(double)*16);
//        }
//
//        //detect y sync watermark
//        for(int i=0; i<8; i++)
//        {
//            memcpy(cstatus, istatus[i], 20);
//            kt(cstatus, 0, nKey);
//            dbSyncVal = YSyncWmDetect(y, nWidth, nHeight, goldc, nKey);
//            if(dbSyncVal > 1.5) break;
//        }
//        
//        if(dbSyncVal <= 1.5)
//        {
//            for(int j=0; j<n_k; j++)
//            {
//                nKey = kqueue[j];
//                memcpy(cstatus, squeue[j], 20);
//                dbSyncVal = YSyncWmDetect(y, nWidth, nHeight, goldc, nKey);
//                if(dbSyncVal > 1.5)
//                {
//                    if(j > 0)
//                    {
//                        int keyq[16];
//                        unsigned char st[16][20];
//                        
//                        memcpy(keyq, kqueue, j*sizeof(int));
//                        memcpy(&kqueue[1], keyq, j*sizeof(int));
//                        kqueue[0] = nKey;
//                        memcpy(st, squeue, j*20);
//                        memcpy(squeue[1], st, j*20);
//                        memcpy(squeue, cstatus, 20);
//                    }
//                    break;
//                }
//            }
//        }
//        
//        if(dbSyncVal > 1.5)
//        {
//            unsigned int nKey1;
//            for(int j=0; j<4; j++)
//            {
//                nextstatus(cstatus, cstatus1, nKey, (unsigned char)j);
//                kt(cstatus1, nKey, nKey1);
//                addqueue(squeue, kqueue, n_k, cstatus1, nKey1);
//            }
//            
//            if(n%64 == 0)
//                bSync[63] = TRUE;
//            else
//                bSync[(n%64)-1] = TRUE;
//        }
//        else
//        {
//            if(n%64 == 0)
//                bSync[63] = FALSE;
//            else
//                bSync[(n%64)-1] = FALSE;
//        }
//        
//        if(n%64 == 0)
//        {
//            CString strText1;
//            char szText[32];
//            
//            int n1 = 0;
//            for(int j=0; j<64; j++)
//            {
//                if(bSync[j])
//                {
//                    sprintf(szText, "%d,", j);
//                    strText1 += szText;
//                    n1 ++;
//                }
//            }
//            
//            CString strText;
//            if(n1 > 0)
//                strText.Format(_T("%d~%d帧共%d帧"), n-64, n-1, n1);
//            else
//                strText.Format(_T("%d~%d帧没有"), n-64, n-1);
//            strText += _T("检测到同步水印.\r\n");
//            ShowText(strText);
//        }
//        
//        try
//        {
//            file.Seek(nHeight*nWidth/2/2, CFile::current);
//        }
//        catch(...)
//        {
//            break;
//        }
//    };
//    
//    if(n%64 != 0)
//    {
//        CString strText1;
//        char szText[32];
//        
//        int n1 = 0;
//        for(int j=0; j<n%64; j++)
//        {
//            if(bSync[j])
//            {
//                sprintf(szText, "%d,", j);
//                strText1 += szText;
//                n1 ++;
//            }
//        }
//        
//        CString strText;
//        if(n1 > 0)
//            strText.Format(_T("%d~%d帧共%d帧"), n-n%64, n-1, n1);
//        else
//            strText.Format(_T("%d~%d帧没有"), n-n%64, n-1);
//        strText += _T("检测到同步水印.\r\n");
//        ShowText(strText);
//    }
//    
//    if(y) free(y);
//    if(u) free(u);
//    
//    file.Close();
//    
//    if(n == 0) return FALSE;
//    return TRUE;
//}

void UMeanWatermark(unsigned char *u, int width, int height, short w, int index)
{
    short block[8][8];
    double coeff[64];
    double alpha = 4.0;
    
    switch(m_dvwmSysParam.nGWmStrengthIndex)
    {
        case 0:
            alpha = 3.2; break;
        case 1:
            alpha = 4.0; break;
        case 2:
            alpha = 4.8; break;
        case 3:
            alpha = 5.6; break;
        case 4:
            alpha = 6.4; break;
        case 5:
            alpha = 7.2; break;
        default:
            alpha = 4.0; break;
    }
    
    for(int i=0; i<width/8; i++)
    {
        for(int j=0; j<height/8; j++)
        {
            GetBlock(width, height, i, j, block, u);
            BlockDCT(block, coeff);
            
            for(int k=0; k<16; k++)
            {
                if(w & (0x01<<k))
                    coeff[0] += alpha*(double)gold[k][index];
                else
                    coeff[0] -= alpha*(double)gold[k][index];
            }
            
            BlockIDCT(coeff, block, 255);
            SetBlock(width, height, i, j, block, u);
        }
    }
}


void UMeanWMDetect(unsigned char *u, int width, int height, int index, double *dbVal, double *dbSum)
{
    short block[8][8];
    double coeff[64];
    
    for(int i=0; i<width/8; i++)
    {
        for(int j=0; j<height/8; j++)
        {
            GetBlock(width, height, i, j, block, u);
            BlockDCT(block, coeff);
            
            for(int k=0; k<16; k++)
            {
                dbVal[k] += coeff[0] * (double)gold[k][index];
                dbSum[k] += coeff[0];
            }
        }
    }
}

void YSyncWatermark(unsigned char *y, int width, int height, short goldc[][63], unsigned int key)
{
    short block[8][8];
    double coeff[64];
    double alpha = 2.7;
    
    switch(m_dvwmSysParam.nFWmStrengthIndex)
    {
        case 0:
            alpha = 2.7; break;
        case 1:
            alpha = 3.0; break;
        case 2:
            alpha = 3.3; break;
        case 3:
            alpha = 3.6; break;
        case 4:
            alpha = 3.9; break;
        case 5:
            alpha = 4.2; break;
        default:
            alpha = 2.7; break;
    }
    
    srand(key);
    
    int n = width*height/8/8/63;
    int *idxpool[20];
    for(int i=0; i<20; i++)
    {
        idxpool[i] = (int *)malloc(n*sizeof(int));
        for(int j=0; j<n; j++)
        {
            idxpool[i][j] = 64*rand()/(RAND_MAX+1);
        }
    }
    
    int m;
    for(int i=0; i<width/8; i++)
    {
        for(int j=0; j<height/8; j++)
        {
            m = i*(height/8)+j;
            GetBlock(width, height, i, j, block, y);
            BlockDCT(block, coeff);
            
            if(m < n*63)
            {
                coeff[1] += alpha*(double)goldc[idxpool[0][m/63]][m%63];
                coeff[8] += alpha*(double)goldc[idxpool[1][m/63]][m%63];
                coeff[2] += alpha*(double)goldc[idxpool[2][m/63]][m%63];
                coeff[9] += alpha*(double)goldc[idxpool[3][m/63]][m%63];
                coeff[16] += alpha*(double)goldc[idxpool[4][m/63]][m%63];
                coeff[3] += alpha*(double)goldc[idxpool[5][m/63]][m%63];
                coeff[10] += alpha*(double)goldc[idxpool[6][m/63]][m%63];
                coeff[17] += alpha*(double)goldc[idxpool[7][m/63]][m%63];
                coeff[24] += alpha*(double)goldc[idxpool[8][m/63]][m%63];
                coeff[4] += alpha*(double)goldc[idxpool[9][m/63]][m%63];
                coeff[11] += alpha*(double)goldc[idxpool[10][m/63]][m%63];
                coeff[18] += alpha*(double)goldc[idxpool[11][m/63]][m%63];
                coeff[25] += alpha*(double)goldc[idxpool[12][m/63]][m%63];
                coeff[32] += alpha*(double)goldc[idxpool[13][m/63]][m%63];
                coeff[5] += alpha*(double)goldc[idxpool[14][m/63]][m%63];
                coeff[12] += alpha*(double)goldc[idxpool[15][m/63]][m%63];
                coeff[19] += alpha*(double)goldc[idxpool[16][m/63]][m%63];
                coeff[26] += alpha*(double)goldc[idxpool[17][m/63]][m%63];
                coeff[33] += alpha*(double)goldc[idxpool[18][m/63]][m%63];
                coeff[40] += alpha*(double)goldc[idxpool[19][m/63]][m%63];
                BlockIDCT(coeff, block, 255);
            }
            
            SetBlock(width, height, i, j, block, y);
        }
    }
    
    for(int i=0; i<20; i++)
        free(idxpool[i]);
}

double YSyncWmDetect(unsigned char *y, int width, int height, short goldc[][63], unsigned int key)
{
    double dVal = 0.F;
    short block[8][8];
    double coeff[64];
    
    srand(key);
    
    int n = width*height/8/8/63;
    int *idxpool[20];
    double *dVals[20];
    double *dValg[20];
    for(int i=0; i<20; i++)
    {
        idxpool[i] = (int *)malloc(n*sizeof(int));
        dVals[i] = (double *)malloc(n*sizeof(double));
        dValg[i] = (double *)malloc(n*sizeof(double));
        for(int j=0; j<n; j++)
        {
            idxpool[i][j] = 64*rand()/(RAND_MAX+1);
        }
        
        memset(dVals[i], 0, sizeof(double)*n);
        memset(dValg[i], 0, sizeof(double)*n);
    }
    
    int m;
    for(int i=0; i<width/8; i++)
    {
        for(int j=0; j<height/8; j++)
        {
            m = i*(height/8)+j;
            GetBlock(width, height, i, j, block, y);
            BlockDCT(block, coeff);
            
            if(m < n*63)
            {
                dVal += coeff[1] * (double)goldc[idxpool[0][m/63]][m%63];
                dVal += coeff[8] * (double)goldc[idxpool[1][m/63]][m%63];
                dVal += coeff[2] * (double)goldc[idxpool[2][m/63]][m%63];
                dVal += coeff[9] * (double)goldc[idxpool[3][m/63]][m%63];
                dVal += coeff[16] * (double)goldc[idxpool[4][m/63]][m%63];
                dVal += coeff[3] * (double)goldc[idxpool[5][m/63]][m%63];
                dVal += coeff[10] * (double)goldc[idxpool[6][m/63]][m%63];
                dVal += coeff[17] * (double)goldc[idxpool[7][m/63]][m%63];
                dVal += coeff[24] * (double)goldc[idxpool[8][m/63]][m%63];
                dVal += coeff[4] * (double)goldc[idxpool[9][m/63]][m%63];
                dVal += coeff[11] * (double)goldc[idxpool[10][m/63]][m%63];
                dVal += coeff[18] * (double)goldc[idxpool[11][m/63]][m%63];
                dVal += coeff[25] * (double)goldc[idxpool[12][m/63]][m%63];
                dVal += coeff[32] * (double)goldc[idxpool[13][m/63]][m%63];
                dVal += coeff[5] * (double)goldc[idxpool[14][m/63]][m%63];
                dVal += coeff[12] * (double)goldc[idxpool[15][m/63]][m%63];
                dVal += coeff[19] * (double)goldc[idxpool[16][m/63]][m%63];
                dVal += coeff[26] * (double)goldc[idxpool[17][m/63]][m%63];
                dVal += coeff[33] * (double)goldc[idxpool[18][m/63]][m%63];
                dVal += coeff[40] * (double)goldc[idxpool[19][m/63]][m%63];
                
                dVals[0][m/63] += coeff[1];
                dVals[1][m/63] += coeff[8];
                dVals[2][m/63] += coeff[2];
                dVals[3][m/63] += coeff[9];
                dVals[4][m/63] += coeff[16];
                dVals[5][m/63] += coeff[3];
                dVals[6][m/63] += coeff[10];
                dVals[7][m/63] += coeff[17];
                dVals[8][m/63] += coeff[24];
                dVals[9][m/63] += coeff[4];
                dVals[10][m/63] += coeff[11];
                dVals[11][m/63] += coeff[18];
                dVals[12][m/63] += coeff[25];
                dVals[13][m/63] += coeff[32];
                dVals[14][m/63] += coeff[5];
                dVals[15][m/63] += coeff[12];
                dVals[16][m/63] += coeff[19];
                dVals[17][m/63] += coeff[26];
                dVals[18][m/63] += coeff[33];
                dVals[19][m/63] += coeff[40];
                
                dValg[0][m/63] += (double)goldc[idxpool[0][m/63]][m%63];
                dValg[1][m/63] += (double)goldc[idxpool[1][m/63]][m%63];
                dValg[2][m/63] += (double)goldc[idxpool[2][m/63]][m%63];
                dValg[3][m/63] += (double)goldc[idxpool[3][m/63]][m%63];
                dValg[4][m/63] += (double)goldc[idxpool[4][m/63]][m%63];
                dValg[5][m/63] += (double)goldc[idxpool[5][m/63]][m%63];
                dValg[6][m/63] += (double)goldc[idxpool[6][m/63]][m%63];
                dValg[7][m/63] += (double)goldc[idxpool[7][m/63]][m%63];
                dValg[8][m/63] += (double)goldc[idxpool[8][m/63]][m%63];
                dValg[9][m/63] += (double)goldc[idxpool[9][m/63]][m%63];
                dValg[10][m/63] += (double)goldc[idxpool[10][m/63]][m%63];
                dValg[11][m/63] += (double)goldc[idxpool[11][m/63]][m%63];
                dValg[12][m/63] += (double)goldc[idxpool[12][m/63]][m%63];
                dValg[13][m/63] += (double)goldc[idxpool[13][m/63]][m%63];
                dValg[14][m/63] += (double)goldc[idxpool[14][m/63]][m%63];
                dValg[15][m/63] += (double)goldc[idxpool[15][m/63]][m%63];
                dValg[16][m/63] += (double)goldc[idxpool[16][m/63]][m%63];
                dValg[17][m/63] += (double)goldc[idxpool[17][m/63]][m%63];
                dValg[18][m/63] += (double)goldc[idxpool[18][m/63]][m%63];
                dValg[19][m/63] += (double)goldc[idxpool[19][m/63]][m%63];
            }
        }
    }
    
    for(int i=0; i<20; i++)
    {
        for(int j=0; j<n; j++)
            dVal -= dVals[i][j]*dValg[i][j]/63.0;
        
        free(idxpool[i]);
        free(dVals[i]);
        free(dValg[i]);
    }
    
    dVal /= (double)n*20.0*63.0;
    
    return dVal;
}
